// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import {getInits, getRankInit} from "./testConfig";

const {ccclass, property} = cc._decorator;

@ccclass
export default class test extends cc.Component {

    @property(cc.Graphics)
    bgGdi: cc.Graphics = null;
    @property(cc.Graphics)
    gdi: cc.Graphics = null;
    @property()
    oneSize: number = 10;
    @property()
    nNextTime: number = 1;
    @property()
    xyCount: number = 70;
    @property(cc.Color)
    falseColor: cc.Color = cc.color();
    @property(cc.Color)
    trueColor: cc.Color = cc.color();

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    private m_ary: boolean[][] = [];
    private m_currOffspring: number = 0;

    protected start() {
        this.initGame();
        this.oneOffspring();
        this.schedule(this.onNextStep.bind(this), this.nNextTime);
    }

    protected initGame() {
        //
        for (let i = 0; i < this.xyCount; i++) {
            if (i % 10 == 0) {
                this.bgGdi.lineWidth = 1.5;
            } else {
                this.bgGdi.lineWidth = 1;
            }
            this.bgGdi.moveTo(0, i * this.oneSize);
            this.bgGdi.lineTo(this.oneSize * this.xyCount, i * this.oneSize);
            this.bgGdi.moveTo(i * this.oneSize, 0);
            this.bgGdi.lineTo(i * this.oneSize, this.oneSize * this.xyCount);
            this.bgGdi.stroke();

            this.m_ary[i] = [];
            for (let j = 0; j < this.xyCount; j++) {
                this.m_ary[i][j] = false;
                this.showOne(i, j, false);
            }
        }
        this.bgGdi.lineWidth = 1.5;
        this.bgGdi.moveTo(0, this.xyCount * this.oneSize);
        this.bgGdi.lineTo(this.oneSize * this.xyCount, this.xyCount * this.oneSize);
        this.bgGdi.moveTo(this.xyCount * this.oneSize, 0);
        this.bgGdi.lineTo(this.xyCount * this.oneSize, this.oneSize * this.xyCount);
        this.bgGdi.stroke();
        this.gdi.stroke();
        //
    }

    protected isCanLife(i: number, j: number, currLife: boolean, srcArray: number[][]): boolean {
        let roundCount = 0;
        for (let x = i - 1; x <= i + 1; x++) {
            for (let y = j - 1; y <= j + 1; y++) {
                if (srcArray[x] && srcArray[x][y]) {
                    if (x == i && y == j) continue;
                    roundCount++;
                }
            }
        }
        if (roundCount == 3) return true;
        if (roundCount == 2) return currLife;
        return false;
    }

    //第一代
    protected oneOffspring() {
        let xy = Math.floor(this.xyCount / 2);
        const ary = getRankInit(xy - 40, xy + 20, 50);
        for (let i = 0; i < ary.length; i++) {
            let x = ary[i].i;
            let y = ary[i].j
            this.m_ary[x][y] = true;
            this.showOne(x, y, true)
        }
        this.gdi.stroke();
        this.m_currOffspring = 1;
    }

    protected onNextStep() {
        const srcArray = JSON.parse(JSON.stringify(this.m_ary));
        for (let i = 0; i < this.xyCount; i++) {
            for (let j = 0; j < this.xyCount; j++) {
                let curLife = this.m_ary[i][j];
                this.m_ary[i][j] = this.isCanLife(i, j, this.m_ary[i][j], srcArray);
                if (curLife != this.m_ary[i][j]) {
                    this.showOne(i, j, this.m_ary[i][j]);
                }
            }
        }
        this.gdi.stroke();
        this.m_currOffspring++;
    }

    protected showOne(i: number, j: number, isLife: boolean) {
        this.gdi.fillColor = isLife ? this.trueColor : this.falseColor;
        this.gdi.fillRect(i * this.oneSize + 1, j * this.oneSize + 1, this.oneSize - 2, this.oneSize - 2);
    }
}
































